<?php

if (!defined('BASEPATH'))
  exit('No direct script access allowed');

/**
 * Trieda urcena na importovanie a exportovanie eventov uzivatelov
 * 
 * 
 * @author Marek Letavay 
 */
class ImEx extends CI_Controller {

  function __construct() {
    parent::__construct();
    $this->load->model('imex_model');
    if (!isLogged())
      redirect('login');
    $this->load->library('form_validation');
  }

  function index() {
    $data["message"] = "Import/export";
    $this->load->view("base_view", $data);
  }

  /**
   * Metóda zavolá exportEvents v Import_export_model, ktorý vráti údaje na export. 
   * <br>Tieto sa upravia do príslušnej podoby a zapíšu sa do daného súboru.
   * @param string $file súbor do ktorého budú exportované dáta.
   * @param string $condition  podmienka pre export údajov.
   */
  function exportEvents($file, $condition) {
    $this->load->helper('file');
    $this->load->model("imex_model");


    $ical = "BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//hacksw/handcal//NONSGML v1.0//EN
X-WR-TIMEZONE:Europe/Bratislava
";

   
    foreach ($this->imex_model->exportEvents($condition) AS $event) {
      $ical .="BEGIN:VEVENT
UID:" . md5(uniqid(mt_rand(), true)) . "@yourhost.test
DTSTAMP:" . gmdate('Ymd') . 'T' . gmdate('His') . "Z
";

      if (strlen($event["day"]) > 3) {
        $ical .= "DTSTART;TZID=Europe/Bratislava:" . $this->delDashFromDate($event["day"]) . "T"
                . getTimeFromMinutes($event["start_time"]) . "00
DTEND;TZID=Europe/Bratislava:" . $this->delDashFromDate($event["day"]) . "T"
                . getTimeFromMinutes($event["end_time"]) . "00
LOCATION:" . $event["room"] . "
";
      } else {
        //ak je to opakujuca udalost 
        $ical .= "DTSTART;TZID=Europe/Bratislava:" . $this->getFirstDate($event["day"]) . "T"
                . getTimeFromMinutes($event["start_time"]) . "00
DTEND;TZID=Europe/Bratislava:" . $this->getFirstDate($event["day"]) . "T"
                . getTimeFromMinutes($event["end_time"]) . "00
LOCATION:" . $event["room"] . "
RRULE:FREQ=WEEKLY;UNTIL=";
        //zadanie konca semestra
        if ($this->isWinterTerm()) {
          $ical .= date("Y") . "1223";
        } else {
          $ical .= date("Y") . "0531";
        }

        $ical .="T000000Z
";
      }
      $ical .="DESCRIPTION:" . $event["description"] . " \\n" . $event["teachers_list"] . "
SUMMARY:" . $event["event_type"] . "
END:VEVENT
";
    }

    $ical .= "END:VCALENDAR";

    if (!write_file('./temp/export.ics', $ical)) {

      echo 'Unable to write the file';
    } else {
      $this->download($file);
    }
  }

  /**
   * Metoda zmeni format datumu z YYYY-MM-DD na YYYYMMDD
   * @param string $date povodny datum
   * @return string zmeneny datum
   */
  function delDashFromDate($date) {
    return substr($date, 0, 4) . substr($date, 5, 2) . substr($date, 8, 2);
  }

  /**
   * Metoda zisti datum prveho zadaneho dna na zaciatku semestra
   * <br>v zimnom - september
   * <br>v letnom - februar
   * 
   * @param string $day hladany den
   * @return string datum v tvare YYYY/MM/DD
   */
  function getFirstDate($day) {
    if ($this->isWinterTerm()) {
      $string = "September " . date("Y") . " " . $this->getFullDayName($day);
    } else {
      $string = "February " . date("Y") . " " . $this->getFullDayName($day);
    }
    return date("Ymd", strtotime($string));
  }

  /**
   * Metoda vrati cele meno daneho dna zadaneho ako parameter
   * @param string $day cislo zadaneho dna
   * @return string cele meno dna v anglictine
   */
  function getFullDayName($day) {
    switch ($day) {
      case "1": return "Monday";
      case "2" : return "Tuesday";
      case "3" : return "Wednesday";
      case "4" : return "Thursday";
      case "5" : return "Friday";
    }
  }

  /**
   * Metoda vrati poradove cislo dna zadaneho ako parameter
   * @param string $day zadany den
   * @return string cislo dna v tyzdni
   */
  function getShortDayName($day) {
    switch ($day) {
      case "Monday": return "1";
      case "Tuesday" : return "2";
      case "Wednesday" : return "3";
      case "Thursday" : return "4";
      case "Friday" : return "5";
    }
  }

  /**
   * Metoda vrati ci je momentalne zimny semester
   * @return TRUE ak je zimny semester inak FALSE
   *
   */
  function isWinterTerm() {
    if ((date("m") >= 9)) {
      return TRUE;
    }
    else
      return FALSE;
  }

  /**
   * Metoda na stiahnutie suboru v ktorom su vyexportovane eventy
   * @param string $file
   */
  function download($file) {
    $this->load->helper('download');

    $data = file_get_contents('./temp/export.ics'); 
    force_download($file, $data);
  }

  /**
   * Metóda načíta údaje zo vstupného súboru a vytvorí dátovú štruktúru, 
   * ktorá sa pošle metóde importEvents() v Import_export_model.
   * @param type $file súbor obsahujúci dáta na importovanie.
   */
  function importEvents($file) {
    $file = './temp/' . $file;
    $this->load->model('imex_model');
    if (preg_match("/^(.*)\.ics$/", $file)) {
      if (file_exists($file)) {
        $result_array = array("user" => $this->session->userdata["user_id"], "events" => $this->get_event_array($file));
        $result = $this->imex_model->importEvents($result_array);
      } else {
        $result = FALSE;
      }
    } else {
      $result = FALSE;
    }
    return $result;
  }

  /**
   * Metoda rozparsuje zadany subor a vrati pole eventov
   * @param string $filepath subor na import
   * @return array|string pole eventov 
   */
  function get_event_array($filepath) {
    $handle = @fopen($filepath, "r");
    if ($handle) {
      $result_array = array();

      while (($line = fgets($handle, 4096)) !== FALSE) {

        $parts = explode(":", $line);
        $key = $parts[0];

        switch ($key) {
          case "BEGIN":
            if (strpos($parts[1], "VEVENT") !== FALSE) {
              $event_array = array();
            }
            break;

          case "END":
            if (strpos($parts[1], "VEVENT") !== FALSE) {
              if ($event_array["repeat"]) {
                $event_array["day"] = $this->getShortDayName($day);
              } else {
                $event_array["day"] = addDashToDate($date);
              }

              array_push($result_array, $event_array);
              $event_array["repeat"] = FALSE;
            }
            break;

          case "LOCATION":
            $event_array["room"] = trim($parts[1]);
            break;

          case "DESCRIPTION":
            $event_array["description"] = substr($parts[1], 0, strpos($parts[1], '\n'));
          case "SUMMARY":
            $event_array["event_type"] = trim($parts[1]);
            break;

          case "RRULE":
            $event_array["repeat"] = TRUE;
            break;

          default:
            if (strpos($key, "DTSTART") !== FALSE) {
              $day = $this->getDayFromDate(substr($parts[1], 0, 8));
              $date = substr($parts[1], 0, 8);
              $event_time = substr($parts[1], 9, 4);
              $event_array["start_time"] = getMinutesFromTime(substr($event_time, 0, 2), substr($event_time, 2, 2));
            } elseif (strpos($key, "DTEND") !== FALSE) {
              $event_time = substr($parts[1], 9, 4);
              $event_array["end_time"] = getMinutesFromTime(substr($event_time, 0, 2), substr($event_time, 2, 2));
            }
        }
      }
      fclose($handle);
      return $result_array;
    } else {
      return array();
    }
  }

  /**
   * Metoda vrati den zo zadaneho datumu
   * @param string $date datum 
   */
  function getDayFromDate($date) {
    $h = mktime(0, 0, 0, substr($date, 4, 2), substr($date, 6, 2), substr($date, 0, 4));
    $w = date("l", $h);
    return $w;
  }
  
  /**
   * Metoda zmeni format datumu z YYYYMMDD na YYYY-MM-DD
   * @param string $date povodny datum
   * @return string zmeneny datum
   */
  function addDashToDate($date){
    $new_date = substr($date, 0, 4) .'-'. substr($date, 4, 2) .'-'. substr($date, 6, 2); 
    return $new_date;
  }

}



?>
